local _version = "0.8-20400"
local tinsert = table.insert
local type, next, pairs, getglobal = type, next, pairs, getglobal
local tostring, tonumber = tostring, tonumber
local string = string

-- table with all the keys in it.  each key is a table
local _bindings = {}

local _entries = {}

if (not BindingsReminder) then BindingsReminder = {} end
local BindingsReminder = BindingsReminder

-- to hold button stuff
BindingsReminder.bLayout = {}

local permutations = {"SHIFT","CTRL","ALT","ALT-SHIFT","ALT-CTRL","CTRL-SHIFT","ALT-CTRL-SHIFT"}
local function _buildBindingsTable()
	local keyTbl
	local action
	for i=1,#BindingsReminder.cLayout do
		local button = BindingsReminder.cLayout[i]
		if (type(button) == "table") then button = button[1] end
		action = GetBindingAction(button)
		if (action and action ~= "") then
			if (not _bindings[button]) then _bindings[button] = {} end
			_bindings[button]['command'] = action
		else
			if _bindings[button] then
				_bindings[button]['command'] = nil
			end
		end
		for j=1,#permutations do
			action = GetBindingAction(permutations[j].."-"..button)
			if (action and action ~= "") then
				if (not _bindings[button]) then _bindings[button] = {} end
				_bindings[button][permutations[j]] = action
			else
				if (_bindings[button]) then
					_bindings[button][permutations[j]] = nil
				end
			end
		end
	end
end

function BindingsReminder.DumpBadKeys()
	for button,tbl in pairs(_bindings) do
		local frame = BindingsReminder.bLayout[button]
		if (not frame or #frame < 1) then
			DEFAULT_CHAT_FRAME:AddMessage(string.format("Button not found: |cFFFF0000%s|r",button))
		else
			DEFAULT_CHAT_FRAME:AddMessage(string.format("Button found: |cFF00FF00%s|r",button))
		end
	end
end

function BindingsReminder.Tooltip(f)
	local key = _entries[f]
	local val = GetBindingText(key,"KEY_")
	GameTooltip_SetDefaultAnchor(GameTooltip,UIParent)
	GameTooltip:AddLine(val)
	if (_bindings[key]) then
		GameTooltip:AddLine()
		--GameTooltip:AddLine(string.format("Command: %s",tostring(_bindings[key]['command'])),.85,.85,.85,1)
		for combo,command in pairs(_bindings[key]) do
			local command2 = getglobal("BINDING_NAME_"..command)
			GameTooltip:AddLine(string.format("|cFFFF0000%s|r: %s",tostring(combo),command2 or tostring(command)),.85,.85,.85,1)
		end
	end
	GameTooltip:Show()
end

function BindingsReminder.UpdateTable()
	_buildBindingsTable()
	local frames = _entries
	for frame in pairs(_entries) do
		if (frame and type(frame.UnlockHighlight) == "function") then
			frame:UnlockHighlight()
		end
	end
	for button,tbl in pairs(_bindings) do
		if next(tbl) then
			local frames = BindingsReminder.bLayout[button]
			if (next(frames)) then
				for i=1,#frames do
					if (frames[i] and type(frames[i].LockHighlight) == "function") then frames[i]:LockHighlight() end
				end
			end
		end
	end
end

function BindingsReminder.CreateKeyBoard()
	BindingsReminder.cLayout = BindingsReminder.qwerty
end

local function _getKey(key)
	if (type(BindingsReminder.cLayout[key]) == "table") then
		return BindingsReminder.cLayout[key][1]
	else
		return BindingsReminder.cLayout[key]
	end
end

local function _getText(key)
	if (type(BindingsReminder.cLayout[key]) == "table") then
		return BindingsReminder.cLayout[key][2]
	else
		return BindingsReminder.cLayout[key]
	end
end

function BindingsReminder.SetText(f)
	local name = f:GetName()
	local key = string.match(name,"^BR_(.+)$")
	local test = _getKey(tonumber(key))
	if (test) then
		_entries[f] = test
	end
	getglobal(f:GetName().."Text"):SetText(_getText(tonumber(key)))
end

function BindingsReminder.KeyToKey(f)
	local entry = _entries[f]
	if (not BindingsReminder.bLayout[entry]) then BindingsReminder.bLayout[entry] = {} end
	tinsert(BindingsReminder.bLayout[entry],f)
end

function BindingsReminder.DumpBindingsTable()
	_buildBindingsTable()
end

function BindingsReminder.CommandHandler(msg)
	msg = string.lower(msg)
	if (msg == "show") then
		-- show the GUI
		BindingsReminderFrame:Show()
	elseif (msg == "hide") then
		-- hide the GUI
		BindingsReminderFrame:Hide()
	elseif (msg == "dumpbad") then
		BindingsReminder.DumpBadKeys()
	--elseif (msg == "help") then
	else
		DEFAULT_CHAT_FRAME:AddMessage("BindingsReminder v".._version)
		DEFAULT_CHAT_FRAME:AddMessage("show: show the keyboard")
		DEFAULT_CHAT_FRAME:AddMessage("hide: hide the keyboard")
	end
end

local _found = false
for cmd in pairs(SlashCmdList) do
	local i = 1
	local pre = "SLASH_"..cmd
	local test = getglobal(pre..i)
	while test do
		if (test == "/br") then
			_found = true
			break
		end
		i = i + 1
		test = getglobal(pre..i)
	end
end
SLASH_BINDINGSREMINDER1 = "/bindingsreminder"
if (not _found) then SLASH_BINDINGSREMINDER2 = "/br" end
SlashCmdList["BINDINGSREMINDER"] = BindingsReminder.CommandHandler

local f = CreateFrame("Frame")
local onEvent = function(frame, event, ...)
	local func = BindingsReminder[event]
	if func and type(func) == "function" then
		func(...)
	end
end

local onShow = function(frame)
	BindingsReminder.UpdateTable()
	BindingsReminderFrame:Show()
end

local onHide = function(frame)
	BindingsReminder.UpdateTable()
	BindingsReminderFrame:Hide()
end

f:SetScript("OnEvent", onEvent)
f:RegisterEvent("ADDON_LOADED")

function BindingsReminder.ADDON_LOADED(addon)
	if addon == "Blizzard_BindingUI" then
		KeyBindingFrame:HookScript("OnShow", onShow)
		KeyBindingFrame:HookScript("OnHide", onHide)
		KeyBindingFrame:HookScript("OnKeyDown", onHide)
	end
end
--myBindings = _bindings
